#include "mainwindow.h"
#include "ui_mainwindow.h"

int MainWindow::TextSum = 1;
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->port->setText("8080"); // 设置默认端口号
    ui->ip->setText("127.0.0.1"); // 设置默认Ip
    ui->record->setReadOnly(true);
    ui->sendFile->setEnabled(false);
    ui->selFile->setEnabled(false);
    //ui->C_status->setText("未连接");

    // 插入事件过滤器
    KeyFilter* k = new KeyFilter(ui->sendMsg, ui->clean, ui->selFile, ui->sendFile);
    //KeyFilter* k = new KeyFilter;
    ui->msg->installEventFilter(k);

    printHostIPAddresses();

    setWindowTitle("客户端") ;
    ui->disconnect->setDisabled(true);

    // 创建AllFolder
    {
        // 获取当前路径
        QDir currentDir = QDir::currentPath();

        // 定义要创建的文件夹名称
        QString folderName = "AllFolder";

        // 构造完整的文件夹路径
        QString folderPath = currentDir.absoluteFilePath(folderName);

        //QDir().mkpath(folderPath);

        // 创建文件夹
        if (QDir().mkpath(folderPath)) {
            ui->record->append("AllFolder created successfully!");
            qDebug() << "文件夹创建成功: " << folderPath;
        } else {
            qDebug() << "文件夹创建失败: " << folderPath;
            ui->record->append("<font color=\"#FF0000\"> AllFolder created failed! </font> ");
        }
    }

    // 实例化监听的套接字对象
    m_tcp = new QTcpSocket(this);
   
    connect(m_tcp,&QTcpSocket::readyRead,this,[=](){
        QByteArray data = m_tcp->readAll();
        QString all = QString::fromUtf8(data);
        if(all.size() > 62)
        {
            // 文件转存:
            QString host;
            for(auto e : all)
            {
                if(e == ":")
                {
                    //host += e;
                    break;
                }
                host += e;
            }
            QString all2 = all.mid(host.size() + 1);
            QByteArray data2 = all2.toUtf8();


            // 创建发送方ip为名的文件夹用于存放文件
            QDir hostDir = QDir::currentPath() + "/AllFolder/" + host;
            QString folderPath = hostDir.absolutePath();

            if(!hostDir.exists())
            {
                // mkpath函数: 一并连缺失的父目录一并创建
                if (QDir().mkpath(folderPath)) {
                    ui->record->append("<font color=\"#FF0000\">" + host +
                                       " created successfully！</font> ");
                    qDebug() << "文件夹创建成功: " << folderPath;
                } else {
                    qDebug() << "文件夹创建失败: " << folderPath;
                    ui->record->append("<font color=\"#FF0000\">" + host +
                                       " created failed！</font> ");
                }
            }

            QString filetxt = "/" + QString::number(TextSum) + ".txt";

            QFile* file = new QFile(folderPath + filetxt);
            file->open(QFile::Append);
            file->write(data2);
            file->close();

            // 将文字颜色设置为红色
            ui->record->append("<font color=\"#FF0000\">已成功接收 " + host +
                               " 发送来的文件" + filetxt +"，请及时保存！</font> ");
            TextSum++;
        }
        else
        {
            // 消息追加:
            ui->record->append(data); // 追加进通信记录中
        }
    });

    // 服务器断开连接
    connect(m_tcp, &QTcpSocket::disconnected,this,[=](){
        m_tcp->close();
        //ui->C_status->setText("未连接");
        ui->connect->setText("连接服务器");
        ui->record->append("服务器已断开连接！");

        ui->disconnect->setEnabled(false);
        ui->connect->setDisabled(false);
        ui->sendFile->setEnabled(false);
        ui->selFile->setEnabled(false);
    });

    // 收到信号代表建立了新连接
    connect(m_tcp,&QTcpSocket::connected,this,[=](){
        //ui->C_status->setText("已连接");
        ui->connect->setText("已连接");

        QString msg = MyHost + ": 已成功连接至服务器!";
        m_tcp->write(msg.toUtf8());
        //ui->record->append("已成功连接至服务器，您的Ip为: " + MyHost);
        ui->record->append("<font color=\"#FF0000\">已成功连接至服务器，您的Ip为: " + MyHost + "</font> ");

        ui->disconnect->setEnabled(true);
        ui->connect->setDisabled(true);
        ui->selFile->setEnabled(true);
    });

    // 创建线程对象
    //QThread* t = new QThread;

    // 创建任务对象
    SendFile* worker = new SendFile(m_tcp);

    // worker->moveToThread(t);

    // 处理文件发送(信号和槽的参数类型也是一样的)
    connect(this,&MainWindow::sendFile,worker,&SendFile::sendFile);

    // 处理子线程发送的信号
    connect(worker,&SendFile::writeOver,this,[=](){
        ui->sendFile->setEnabled(false);

        QMessageBox::information(this,"文件发送","文件发送完毕！！！");
    });


   // t->start();
}


// 删除目录
bool removeDirRecursively(const QString &dirPath) {
    QDir dir(dirPath);

    if (!dir.exists() || !dir.isReadable()) {
        qDebug() << "Directory does not exist:" << dirPath;
        return true; // 如果目录不存在，可以认为“删除”操作是成功的
    }

    if (!dir.isReadable()) {
        qDebug() << "Directory is not readable:" << dirPath;
        return false;
    }

    QFileInfoList fileList = dir.entryInfoList(QDir::NoDotAndDotDot |
                                               QDir::AllDirs | QDir::Files);
    foreach (QFileInfo fileInfo, fileList) {
        if (fileInfo.isDir()) {
            // 递归删除子目录
            if (!removeDirRecursively(fileInfo.absoluteFilePath())) {
                return false;
            }
        } else {
            // 删除文件
            if (!QFile::remove(fileInfo.absoluteFilePath())) {
                qDebug() << "Failed to remove file:" << fileInfo.absoluteFilePath();
                return false;
            }
        }
    }

    // 删除空目录本身
    return dir.rmdir(dir.path());
}

MainWindow::~MainWindow()
{    
    QString folderToDelete = QDir::currentPath() + "/AllFolder"; //当前路径 + 指定文件夹

    if (removeDirRecursively(folderToDelete)) {
        qDebug() << "Directory and its contents deleted successfully:" << folderToDelete;
    } else {
        qDebug() << "Failed to delete directory or its contents:" << folderToDelete;
    }

    delete ui;
}


//void MainWindow::on_setListen_clicked()
//{
//    unsigned short port = ui->port->text().toUShort(); // 读出端口号并转换成无符号短整型
//    m_s->listen(QHostAddress::Any, port); // 启动监听，绑定IP与端口
//    ui->setListen->setText("已启用监听");
//    ui->setListen->setEnabled(false); // 绑定后按钮设置为不可用
//}

void MainWindow::on_sendMsg_clicked()
{
    QString msg =": " + ui->msg->toPlainText(); // 将数据以纯文本的方式取出来
    auto it = msg.begin();
    int _m = 1;
    while(*it != ':')
    {
        it++;
        ++_m;
    }

    if(msg.size() - _m > 51)
    {
        ui->record->append("<font color=\"#FF0000\">发送字段过长，请重新尝试！(建议五十字符内)</font> ");
    }
    else
    {
        m_tcp->write(MyHost.toUtf8() + msg.toUtf8());
        ui->record->append("I say" + msg); // 追加进通信记录中
        ui->msg->setText("");
    }
}

void MainWindow::on_connect_clicked()
{
    QString ip = ui->ip->text();
    unsigned short port = ui->port-> text().toUShort();
    m_tcp->connectToHost(ip, port);
}

void MainWindow::on_disconnect_clicked()
{
    QString msg = MyHost + "已与服务器断开连接";// 将数据以纯文本的方式取出来
    m_tcp->write(msg.toUtf8());

    m_tcp->close();
    ui->disconnect->setEnabled(false);
    ui->connect->setDisabled(false);
    ui->record->append("已主动与服务器断开连接！");
}

// 获取主机Ipv4地址
void MainWindow::printHostIPAddresses() {
    QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
    foreach (QNetworkInterface interface, interfaces) {
        if (interface.flags().testFlag(QNetworkInterface::IsUp) && !interface.flags().testFlag(QNetworkInterface::IsLoopBack)) {
            QList<QNetworkAddressEntry> entries = interface.addressEntries();
            foreach (QNetworkAddressEntry entry, entries) {
                // 输出所有类型的IP地址
                //qDebug() << "IP Address:" << entry.ip().toString();

                // 只保留IPv4地址:
                if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
                    //qDebug() << "IPv4 Address:" << entry.ip().toString();
                    MyHost = entry.ip().toString();
                }
            }
        }
    }
}


void MainWindow::on_selFile_clicked()
{
    // 弹出选择文件对话框即可
    QString path = QFileDialog::getOpenFileName(); // 得到某个磁盘文件的绝对路径
    if(path.isEmpty())
    {
        ui->sendFile->setEnabled(false);
    }
    else
    {
        ui->msg->setText(path);
        ui->sendFile->setEnabled(true);
    }
}

void MainWindow::on_sendFile_clicked()
{
    // 发送一个信号告诉子线程让其帮忙发送文件
    emit sendFile(ui->msg->toPlainText(), MyHost);
    ui->msg->setText("");
}


void MainWindow::on_clean_clicked()
{
    ui->record->setText("");
}
